﻿namespace EggOfPanKu.Library.Settings
{
	using System;
	using System.Collections.Generic;
	using System.Configuration;
	using System.IO;
	using System.Linq;
	using System.Reflection;
	using System.Text;
	using WebPaigeDesign.Utilities;

	/// <summary>
	/// A base class for the Customized settings classes
	/// </summary>
	/// Created by Paige on 10/10/2009
	public abstract class CustomSettingsBase : ConfigurationSection
	{
		#region Fields

		private Configuration _baseConfiguration = null;
		private string _executingAssemblyPath = string.Empty;

		#endregion Fields

		#region Properties


		/// <summary>
		/// Gets or sets the base configuration.
		/// </summary>
		/// <value>The base configuration.</value>
		private Configuration BaseConfiguration
		{
			get
			{
				if (_baseConfiguration == null)
				{
					_baseConfiguration = GetConfiguration(this.ConfigurationFileName);
				}
				return _baseConfiguration;
			}
			set { _baseConfiguration = value; }
		}
		/// <summary>
		/// Gets the name of the configuration file.
		/// </summary>
		/// <value>The name of the configuration file.</value>
		protected abstract string ConfigurationFileName
		{
			get;
		}

		/// <summary>
		/// Gets the name of the configuration section.
		/// </summary>
		/// <value>The name of the configuration section.</value>
		protected abstract string ConfigurationSectionName
		{
			get;
		}

		/// <summary>
		/// Gets the executing assembly path.
		/// </summary>
		/// <value>The executing assembly path.</value>
		public string ExecutingAssemblyPath
		{
			get
			{
				if (string.IsNullOrEmpty(_executingAssemblyPath))
				{

					string path = Assembly.GetExecutingAssembly().Location;
					path = path.Substring(0, path.LastIndexOf("\\"));
					_executingAssemblyPath = path;

				}
				return _executingAssemblyPath;
			}
		}

		/// <summary>
		/// Gets the content path.
		/// </summary>
		/// <value>The content path.</value>
		public string ContentPath
		{
			get
			{
				if (string.IsNullOrEmpty(_executingAssemblyPath))
				{
#if DEBUG
                    string path = new DirectoryInfo(Assembly.GetExecutingAssembly().Location)
                        .Parent.Parent.Parent.Parent.FullName;
					//string path = new DirectoryInfo(Environment.CurrentDirectory).Parent.Parent.FullName;
					path = Path.Combine(path, "content");
#else
                    string path = Assembly.GetExecutingAssembly().Location;
                    path = path.Substring(0, path.LastIndexOf("\\"));
#endif
					_executingAssemblyPath = path;

				}
				return _executingAssemblyPath;
			}
		}
		#endregion Properties

		#region Methods

		/// <summary>
		/// Loads the config section.
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <returns></returns>
		/// Created by Paige on 10/10/2009
		public static T LoadConfigSection<T>()
			where T : CustomSettingsBase, new()
		{
			T retval = new T();
			return retval.LoadConfigSection<T>(retval.ConfigurationFileName, retval.ConfigurationSectionName);
		}

		/// <summary>
		/// Saves this instance.
		/// </summary>
		public void Save()
		{
			BaseConfiguration.Save(ConfigurationSaveMode.Minimal);
		}


		/// <summary>
		/// Loads the config section.
		/// </summary>
		/// <param name="Path">The path.</param>
		/// <param name="Section">The section.</param>
		/// <returns></returns>
		protected T LoadConfigSection<T>(string Path, string Section)
			where T : CustomSettingsBase
		{
			Configuration config = GetConfiguration(Path);

			if (config.Sections[Section] == null)
			{
				config.Sections.Add(Section, this);
			}

			this.BaseConfiguration = config;
			return config.GetSection(Section) as T;
		}

		/// <summary>
		/// Gets the configuration object from the path.
		/// </summary>
		/// <param name="Path">The path.</param>
		/// <returns></returns>
		private Configuration GetConfiguration(string Path)
		{
			Configuration config = null;
			ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap();
			configFileMap.ExeConfigFilename = Path;

			config = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None);
			return config;
		}

		#endregion Methods
	}
}